package com.zp.imagecompresspractice.View;

import android.content.Context;
import android.content.res.TypedArray;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.CornerPathEffect;
import android.graphics.Paint;
import android.graphics.Path;
import android.os.Build;
import android.support.annotation.Nullable;
import android.support.annotation.RequiresApi;
import android.support.v4.view.ViewPager;
import android.util.AttributeSet;
import android.util.DisplayMetrics;
import android.util.TypedValue;
import android.view.Gravity;
import android.view.View;
import android.view.ViewGroup;
import android.view.WindowManager;
import android.widget.LinearLayout;
import android.widget.TextView;

import com.socks.library.KLog;
import com.zp.imagecompresspractice.R;

import java.util.ArrayList;
import java.util.List;

/**
 * Created by izp on 2017/7/12.
 */

public class TabView extends LinearLayout {
    private static final float F_INDICATOER_TAB_RATIO = 1.0f / 6;//指示器和单个tab按钮的的比值
    //三角形的最大宽度，三个tab的时候是三角形允许的最大的宽度
    private final int DIMENSION_INDICATOR_WIDTH = (int) (getScreenWidth() / 3 * F_INDICATOER_TAB_RATIO);//在构造器的时候调方法，应该是能调到的
    private Paint mPaint;//画笔，这里用来绘制三角形的
    private Path mPath;//路径，用来确定三角形的轮廓
    private int mIndicatorHeight;//指示器的高度
    private int mIndicatorWidth;//指示器的宽度

    private int mIndicatorTransitionX;//指示器移动的距离，随时变化

    private float mUserTransitionX;//用户的滑动距离，随时变化

    private static final int F_DEFAULT_TAB_COUNT = 4;//默认tab数量

    private int mVisibleTab = F_DEFAULT_TAB_COUNT;//当前可见的tab数量

    private List<String> mTabTitles;//tab名称

    public ViewPager mViewPager;//与之绑定的ViewPager

    private static final int COLOR_TEXT_NORMAL = 0x77FFFFFF; //标题正常时的颜色

    private static final int COLOR_TEXT_HIGHLIGHTCOLOR = 0xFFFFFFFF;//标题选中时的颜色

    private List<TextView> mTabTexts;


    public TabView(Context context) {
        super(context);
        init(context,null);
    }

    public TabView(Context context, @Nullable AttributeSet attrs) {
        super(context, attrs);
        init(context,attrs);
    }

    public TabView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        init(context,attrs);
    }

    @RequiresApi(api = Build.VERSION_CODES.LOLLIPOP)
    public TabView(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
        super(context, attrs, defStyleAttr, defStyleRes);
        init(context,attrs);
    }

    /**
     * @param count
     * 设置可见的tab的数量
     */
    public void setVisibleTabCount(int count){
        this.mVisibleTab = count;
    }

    public void setTabItemTitle(List<String> itemTitles){
//        如果传入的list有值，则移除布局文件中设置的View
        if (null!=itemTitles && itemTitles.size()>0){
            removeAllViews();
            mTabTitles = itemTitles;
            for (int i=0;i<itemTitles.size();i++){
                final int finalI = i;
                addView(generateTextView(mTabTitles.get(i), new OnClickListener() {
                    @Override
                    public void onClick(View view) {
                        mViewPager.setCurrentItem(finalI);
                    }
                }));
            }
        }
    }

    public void bindWithViewPager(ViewPager viewPager,int defaultPosition){
        mViewPager = viewPager;
        mViewPager.addOnPageChangeListener(new ViewPager.OnPageChangeListener() {
            @Override
            public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
                // 滚动
                scroll(position, positionOffset);
            }

            @Override
            public void onPageSelected(int position) {
                setTabHighLight(position);
            }

            @Override
            public void onPageScrollStateChanged(int state) {

            }
        });
        mViewPager.setCurrentItem(defaultPosition);
        setTabHighLight(defaultPosition);

    }

    private void init(Context context, @Nullable AttributeSet attrs){
        KLog.v();
        TypedArray typedArray = context.obtainStyledAttributes(attrs, R.styleable.TabView);
        mVisibleTab = typedArray.getInt(R.styleable.TabView_item_count,F_DEFAULT_TAB_COUNT);
        if (mVisibleTab<0){
            mVisibleTab = F_DEFAULT_TAB_COUNT;
        }
        typedArray.recycle();

//        初始化画笔
        mPaint = new Paint();
        mPaint.setAntiAlias(true);//抗锯齿
        mPaint.setColor(Color.parseColor("#ffffff"));//为毛要初始化成白色？
        mPaint.setPathEffect(new CornerPathEffect(3));//可以设置画笔画出的线条的风格，这个风格是转角的时候圆滑过渡。
    }

    @Override
    protected void dispatchDraw(Canvas canvas) {
        drawIndicator(canvas);
        super.dispatchDraw(canvas);
    }

    /**
     * @param canvas
     * 绘制指示器
     */
    private void drawIndicator(Canvas canvas){

        canvas.save();
//        画笔平移到正确的位置
        canvas.translate(mIndicatorTransitionX + mUserTransitionX,getHeight()+1);//起点的位置，往右初始位置加用户点击位置，Y轴的是在整个view的高的下一个像素
        canvas.restore();//保存这个画布
        KLog.v("canvas.translate(mIndicatorTransitionX "+mIndicatorTransitionX+"+ mUserTransitionX"+mUserTransitionX+",getHeight()+1)"+getHeight()+1);

    }

    @Override
    protected void onSizeChanged(int w, int h, int oldw, int oldh) {
        super.onSizeChanged(w, h, oldw, oldh);
        initIndicator(w,h,oldw,oldh);
    }

    /**
     * @param w
     * @param h
     * @param oldw
     * @param oldh
     * 初始化指示器，的宽度
     */
    private void initIndicator(int w, int h, int oldw, int oldh){
        mIndicatorWidth =(int)(w/mVisibleTab * F_INDICATOER_TAB_RATIO);//当前view的宽度，获得当前单个tab的宽度，然后在获取到indicator的宽度
        mIndicatorWidth = Math.min(DIMENSION_INDICATOR_WIDTH, mIndicatorWidth);

//        mIndicatorWidth = getScreenWidth()/mVisibleTab;//这个肯定不对

//        initTriangle()中用Path去构造了一个三角形，这个很简单了~~
        mPath = new Path();
        mIndicatorHeight = getHeight()/10;//view的高度除以10
        mPath.moveTo(0,0);//对这个没看懂
        mPath.lineTo(mIndicatorWidth,0);//先移动到这个点。
        mPath.lineTo(mIndicatorWidth,-mIndicatorHeight);
        mPath.lineTo(0,-mIndicatorHeight);//对路径的这些点有疑问。
        mPath.close();//封闭这个路径

//        这里还初始化了mInitTranslationX，因为一开始显示的就在第一个Tab的中间位置
//        初始时的偏移量
        mIndicatorTransitionX = getWidth()/mVisibleTab/2- mIndicatorWidth /2;//怎么一会儿是view的宽度一会儿是view宽度呢？

    }





    /**
     * @return 返回的是px 值，获取系统宽度
     */
    private int getScreenWidth(){
        WindowManager windowManager = (WindowManager) getContext().getSystemService(Context.WINDOW_SERVICE);
        DisplayMetrics displayMetrics = new DisplayMetrics();
        windowManager.getDefaultDisplay().getMetrics(displayMetrics);
        return displayMetrics.widthPixels;
    }

    private TextView generateTextView(String string,OnClickListener listener){
        TextView textView = new TextView(getContext());
        LayoutParams layoutParams  = new LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT);
        layoutParams.width = getScreenWidth()/mVisibleTab;//layout的已经设置了宽高为什么不在那个时候就设置了？
        textView.setGravity(Gravity.CENTER);
        textView.setTextColor(COLOR_TEXT_NORMAL);
        textView.setText(string);
        textView.setTextSize(TypedValue.COMPLEX_UNIT_SP,16);
        textView.setLayoutParams(layoutParams);
        if (null!=listener){
            textView.setOnClickListener(listener);
        }
        if (null==mTabTexts){
            mTabTexts = new ArrayList<>();
        }
        mTabTexts.add(textView);
        return textView;
    }

    /**
     * @param position
     * 设置tab文本高亮
     */
    private void setTabHighLight(int position){
        for (int i=0;i<mTabTexts.size();i++){
            if (i==position){
                mTabTexts.get(i).setTextColor(COLOR_TEXT_HIGHLIGHTCOLOR);
            }else {
                mTabTexts.get(i).setTextColor(COLOR_TEXT_NORMAL);
            }
        }
    }

    /**
     * 指示器跟随手指滚动
     * @param position 当前的位置
     * @param offset 移动的距离
     */
    private void scroll(int position,float offset){
//        不断改变偏移量
        mUserTransitionX = getWidth() / mVisibleTab * (position + offset);
        //1、这里的偏移量等于view的宽度除以个数，得到每隔tab的宽度
        //2、tab的宽度乘以当前的位置，再加上offset偏移量。
        KLog.v("重点观察滑动时的状态变化："+"mUserTransitionX："+mUserTransitionX+" = getWidth()："+
                getWidth()+" / mVisibleTab ："+mVisibleTab+"* (position ："+position+" offset："+offset);
        int tabWidth = getScreenWidth() / mVisibleTab;
        KLog.v("为什么这里右计算了一次tabWidth ："+tabWidth+"getScreenWidth()："+getScreenWidth());
        // 容器滚动，当移动到倒数最后一个的时候，开始滚动,这边的1 也可以改成2
        if (offset > 0 && position >= (mVisibleTab - 1) && getChildCount() > mVisibleTab){
            KLog.v("offset ："+offset+"> 0 && position ："+position+"(mVisibleTab ："+mVisibleTab+" getChildCount() ："+getChildCount());
            //这个offset有可能表示方向和力度。
            if (mVisibleTab != 1){
                //1、如果当前可见tab数量不是1，那么
                //2、那么移动到
                scrollTo((position - (mVisibleTab - 1)) * tabWidth+(int) (tabWidth * offset),0);
//                3、可见tab-1，等于最后一个tab的position，
//                4、如果当前position-最后一个position，基本就是负的，最大就是0了，
//                5、这个移动的距离，还是猜不透啊。
                KLog.v("scrollTo((position - (mVisibleTab - 1)) * tabWidth+(int) (tabWidth * offset),0)"+
                        "position："+position+"mVisibleTab："+mVisibleTab+"tabWidth："+tabWidth+"："+"offset："+offset);

            }else {// 为count为1时 的特殊处理
                scrollTo(position * tabWidth + (int) (tabWidth * offset), 0);
                KLog.v("scrollTo(position * tabWidth + (int) (tabWidth * offset), 0)"+
                        "position："+position+"mVisibleTab："+mVisibleTab+"tabWidth："+tabWidth+"："+"offset："+offset);
            }

        }
        invalidate();
    }

    /**
     * 设置布局中view的一些必要属性；如果设置了setTabTitles，布局中view则无效
     * 这个方法貌似没什么意义。
     */
    @Override
    protected void onFinishInflate() {
        super.onFinishInflate();
        int childCount = getChildCount();///me：获取布局中子类的个数是一个很蠢的事情，
        if (childCount ==0){
            return;
        }
        for (int i=0;i<childCount;i++){
            View view = getChildAt(i);
            LayoutParams layoutParams = (LayoutParams) view.getLayoutParams();
            layoutParams.weight = 0;//每个tab之前的比例都是0
            layoutParams.width = getScreenWidth()/mVisibleTab;
            view.setLayoutParams(layoutParams);
        }
    }
}
